package com.markerhub.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.markerhub.common.lang.Const;
import com.markerhub.common.lang.Result;
import com.markerhub.entity.SysRole;
import com.markerhub.entity.SysRoleMenu;
import com.markerhub.entity.SysUserRole;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色管理Controller
 */
@Api(tags = "角色管理")
@RestController
@RequestMapping("/api/sys-role")
public class SysRoleController extends BaseController {

	@ApiOperation(value = "获取角色详情", notes = "根据角色ID获取角色详细信息")
	@PreAuthorize("hasAuthority('sys:role:list')")
	@GetMapping("/detail/{id}")
	public Result detail(@PathVariable("id") Long id) {

		SysRole sysRole = sysRoleService.getById(id);

		// 获取角色相关联的菜单id
		List<SysRoleMenu> roleMenus = sysRoleMenuService.list(new QueryWrapper<SysRoleMenu>().eq("role_id", id));
		List<Long> menuIds = roleMenus.stream().map(p -> p.getMenu_id()).collect(Collectors.toList());

		sysRole.setMenuIds(menuIds);
		return Result.succ(200, "获取角色信息成功", sysRole);
	}

	@ApiOperation(value = "获取角色列表", notes = "获取角色分页列表，支持按名称搜索")
	@PreAuthorize("hasAuthority('sys:role:list')")
	@GetMapping("/list")
	public Result list(String name) {

		Page<SysRole> pageData = sysRoleService.page(getPage(),
				new QueryWrapper<SysRole>()
						.like(StrUtil.isNotBlank(name), "name", name)
		);

		return Result.succ(200, "获取角色分页列表成功", pageData);
	}

	@ApiOperation(value = "查询角色", notes = "查询角色，支持按名称搜索")
	@PreAuthorize("hasAuthority('sys:role:query')")
	@GetMapping("/query")
	public Result query(String name) {
		// 复用list方法的逻辑
		return list(name);
	}

	@ApiOperation(value = "新增角色", notes = "创建新角色")
	@PostMapping("/add")
	@PreAuthorize("hasAuthority('sys:role:add')")
	public Result add(@Validated @RequestBody SysRole sysRole) {

		sysRole.setCreated(LocalDateTime.now());
//		sysRole.setStatus(Const.STATUS_ON);

		sysRoleService.save(sysRole);
		return Result.succ(200, "创建角色成功", sysRole);
	}

	@ApiOperation(value = "更新角色", notes = "更新角色信息")
	@PutMapping("/update")
	@PreAuthorize("hasAuthority('sys:role:update')")
	public Result update(@Validated @RequestBody SysRole sysRole) {

		sysRole.setUpdated(LocalDateTime.now());

		sysRoleService.updateById(sysRole);

		// 更新缓存
		sysUserService.clearUserAuthorityInfoByRoleId(sysRole.getId());

		return Result.succ(200, "更新角色成功", sysRole);
	}

	@ApiOperation(value = "删除单个角色", notes = "根据角色ID删除角色")
	@DeleteMapping("/delete/{id}")
	@PreAuthorize("hasAuthority('sys:role:delete')")
	public Result deleteById(@PathVariable("id") Long id) {
		return delete(new Long[]{id});
	}

	@ApiOperation(value = "批量删除角色", notes = "批量删除多个角色")
	@DeleteMapping("/delete")
	@PreAuthorize("hasAuthority('sys:role:delete')")
	@Transactional
	public Result delete(@RequestBody Long[] ids) {

		sysRoleService.removeByIds(Arrays.asList(ids));

		// 删除中间表
		sysUserRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id", ids));
		sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id", ids));

		// 缓存同步删除
		Arrays.stream(ids).forEach(id -> {
			// 更新缓存
			sysUserService.clearUserAuthorityInfoByRoleId(id);
		});

		return Result.succ(200, "删除角色成功", null);
	}

	@ApiOperation(value = "分配权限", notes = "为角色分配菜单权限")
	@Transactional
	@PutMapping("/perm")
	@PreAuthorize("hasAuthority('sys:role:perm')")
	public Result perm(@RequestBody RolePermAssignDto data) {
		return perm(data.getRoleId(), data.getMenuIds());
	}

	// 内部方法，用于处理权限分配逻辑
	private Result perm(Long roleId, Long[] menuIds) {

		List<SysRoleMenu> sysRoleMenus = new ArrayList<>();

		Arrays.stream(menuIds).forEach(menuId -> {
			SysRoleMenu roleMenu = new SysRoleMenu();
			roleMenu.setMenu_id(menuId);
			roleMenu.setRole_id(roleId);

			sysRoleMenus.add(roleMenu);
		});

		// 先删除原来的记录，再保存新的
		sysRoleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", roleId));
		sysRoleMenuService.saveBatch(sysRoleMenus);

		// 删除缓存
		sysUserService.clearUserAuthorityInfoByRoleId(roleId);

		return Result.succ(200, "分配权限成功", menuIds);
	}

	// 辅助DTO类
	public static class RolePermAssignDto {
		private Long roleId;
		private Long[] menuIds;

		public Long getRoleId() {
			return roleId;
		}

		public void setRoleId(Long roleId) {
			this.roleId = roleId;
		}

		public Long[] getMenuIds() {
			return menuIds;
		}

		public void setMenuIds(Long[] menuIds) {
			this.menuIds = menuIds;
		}
	}

}
